#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <string>
using namespace std;

pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

int ticket = 1000;
void *ThreadFunc(void *args)
{
    string name = (const char *)args;
    while (1)
    {
        pthread_mutex_lock(&mutex);
        if (ticket > 0)
        {
            usleep(1000);
            cout << "i am " << name.c_str() << ", ticket num = " << --ticket << endl;
        }
        else
        {
            cout << "票卖完了，正在浪费锁资源" << endl;
            sleep(1);
        }

        pthread_mutex_unlock(&mutex);
    }
}

void test1()
{
    // 主线程

    pthread_t tid1, tid2, tid3;

    pthread_create(&tid1, nullptr, ThreadFunc, (void *)"Thread one");
    pthread_create(&tid2, nullptr, ThreadFunc, (void *)"Thread two");
    pthread_create(&tid3, nullptr, ThreadFunc, (void *)"Thread three");

    while (1)
    {
        sleep(1);
    }

    pthread_join(tid1, nullptr);
    pthread_join(tid2, nullptr);
    pthread_join(tid3, nullptr);
}


void *ThreadFuncCond(void *args)
{
    string name = (const char *)args;
    while (1)
    {
        pthread_mutex_lock(&mutex);
        if (ticket > 0)
        {
            usleep(1000);
            cout << "i am " << name.c_str() << ", ticket num = " << --ticket << endl;
        }
        else
        {
            cout << name.c_str()<<" say: 票卖完了，正在浪费锁资源" << endl;

            // 处于等待时，会释放锁！
            // 从等待中唤醒时，是在临界区中被唤醒，此时会获得锁！
            // 被唤醒也需要参与锁的竞争
            pthread_cond_wait(&cond, &mutex);   
        }

        pthread_mutex_unlock(&mutex);
    }
}
void test2()
{
    // 主线程

    pthread_t tid1, tid2, tid3;

    pthread_create(&tid1, nullptr, ThreadFuncCond, (void *)"Thread one");
    pthread_create(&tid2, nullptr, ThreadFuncCond, (void *)"Thread two");
    pthread_create(&tid3, nullptr, ThreadFuncCond, (void *)"Thread three");

    sleep(5);
    // 实现条件队列下进行排队
    while (1)
    {
        // 1.首先什么操作都不进行，运行程序观察现象    

        // 2.然后测试这部分代码
        
        // 释放信号唤醒一个处于条件等待下的线程
        // pthread_cond_signal(&cond);
        // sleep(1);

       
        // 3.最后再测试这部分代码
        
        // sleep(10);
        // // 实现每隔10s放出一批票，需要加锁
        // pthread_mutex_lock(&mutex);
        // ticket+=100;
        // pthread_mutex_unlock(&mutex);
        // // 接着发出信号，解除等待条件的阻塞
        // pthread_cond_broadcast(&cond);
        
    }
}
int main()
{
    test2();
}